<?php

namespace App\Services\Oauth\Oauth2;

use Illuminate\Support\Facades\Redis;
use App\Services\Oauth\Oauth2\App;
use App\Services\Oauth\User;
use App\Core\Entity\BaseEntity;
use App\Exceptions\Response\Service\ServiceCode;
use App\Exceptions\Response\Service\ServiceException;
use App\Models\Oauth\AuthorizeModel;
use Think\Auth;

/**
 *处理accessToken-访问令牌
 */
class AccessToken extends BaseEntity
{

    //访问令牌对象包括(id、user_id、token_type、expires_in、scope、access_token、refresh_token、status、created、updated)
    protected $authorize;

    public function __construct(Array $data = array())
    {
        parent::__construct($data);
    }

    /**
     * 查询authorize信息，令牌（access_token）的相关参数
     * 从tw_open_authorize表中查询（user_id、token_type、expores_in、scope、access_token、refresh_token、status、created、updated）
     */
    public function getAuthorize($accessToken)
    {
        if (!$accessToken) {
            throw new ServiceException(ServiceCode::SERVICE_OAUTH_ACCESS_TOKEN_IS_NULL, '', []);
        }
        $data = AuthorizeModel::getAuthorizeByAccessToken($accessToken);
        if (!$data) {
            throw new ServiceException(ServiceCode::SERVICE_OAUTH_ACCESS_TOKEN_IS_ERROR, '', []);
        }
        return $data;
    }

    /**
     * 获取userid
     */
    public function getUserId()
    {
        $uid = $this->authorize['user_id'];
        if (!$uid) {
            throw new ServiceException(ServiceCode::SERVICE_OAUTH_USER_NOT_EXIST, '', []);
        }
        return $uid;
    }

    /**
     * 验证令牌（access_token）
     */
    public function checkAccessToken($accessToken, $scope = 'basic', $type = '')
    {
        //通过token查询授权信息
        $this->authorize = $this->getAuthorize($accessToken);
        if ($scope !== $this->authorize['scope']) {
            //申请的权限范围
            throw new ServiceException(ServiceCode::SERVICE_OAUTH_INVALID_SCOPE, '', []);
        } else if (intval($this->authorize['expires_in']) < intval(time() - $this->authorize['created'])) {
            //access_token 过期(申请的时间和有效期比较)，过期后，客户端访问接口，颁发新的access_token
            throw new ServiceException(ServiceCode::SERVICE_OAUTH_ACCESS_TOKEN_DATED, '', []);
        } else {
            //token 通过验证，刷新access_token的使用时间
            AuthorizeModel::refreshTokenByToken($accessToken);
            return true;
        }
    }

    /**
     * 验证refresh_token
     */
    public static function checkRefreshToken($refreshToken, $scope = 'basic', $grantType)
    {
        if ($grantType !== 'authorization_code') {
            throw new ServiceException(ServiceCode::SERVICE_OAUTH_AUTHORIZATION_CODE_NO_SUPPORTED, '', []);
        }
        $data = AuthorizeModel::getAuthorizeByRefreshToken($refreshToken);
        if (!$data) {
            throw new ServiceException(ServiceCode::SERVICE_OAUTH_REFRESH_TOKEN_IS_ERROR, '', []);
        }
        return $data;
    }

    /**
     * 客户端向认证服务器申请令牌（access_token）
     * 生成access_token信息，并保存到数据库,对应表 tw_open_authorize
     */
    public static function makeAuthorize($scope, $uid)
    {
        $data = AuthorizeModel::createAuthorize($scope, $uid);
        if (!$data) {
            throw new ServiceException(ServiceCode::SERVICE_OAUTH_CREATE_ACCESS_TOKEN_FAIL, '', []);
        }
        return $data;
    }

}